#include <stdio.h>      // 标准输入输出
#include <stdlib.h>         // 标准函数库
//!!!宏 是有顺序的 "wifi_connecter.h"放在前面
#include "wifi_connecter.h" // easy wifi (station模式)
#include <string.h>         // 字符串处理(操作字符数组)
#include "ohos_init.h"  // 用于初始化服务(services)和功能(features)
#include "cmsis_os2.h"  // CMSIS-RTOS API V2
#include "iot_gpio.h"   // OpenHarmony HAL API：IoT硬件设备操作接口-GPIO
#include "hi_io.h"      // 海思Pegasus SDK API：IoT硬件设备操作接口-IO
#include "iot_pwm.h"
#include "hi_pwm.h"
#include "mqtt_task.h"      // MQTT接口
//主线程函数
// 定义一个宏，用于标识SSID。请根据实际情况修改 s
#define PARAM_HOTSPOT_SSID "aaa"

// 定义一个宏，用于标识密码。请根据实际情况修改
#define PARAM_HOTSPOT_PSK "BAIJICHUANG2807"

// 定义一个宏，用于标识加密方式
#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK

// 定义一个宏，用于标识MQTT服务器IP地址。请根据实际情况修改
#define PARAM_SERVER_ADDR "47.120.10.61"

// 定义一个宏，用于标识MQTT服务器端口
#define PARAM_SERVER_PORT "18083"
// 定义GPIO引脚，尽量避免直接用数值
#define LED_GPIO 9//A9 蜂鸣器跟灯用的是同一个引脚HI_IO_NAME_GPIO_9
#define BUTTON_GPIO 5//A5
// 主线程函数

static void GpioTask(void *arg)
{
    (void)arg;
    
    //引脚9
    IoTGpioInit(LED_GPIO);

    //引脚5
    IoTGpioInit(BUTTON_GPIO);
    hi_io_set_func(BUTTON_GPIO, HI_IO_FUNC_GPIO_5_GPIO);
    IoTGpioSetDir(BUTTON_GPIO, IOT_GPIO_DIR_IN);
    hi_io_set_pull(BUTTON_GPIO, HI_IO_PULL_UP); //设置GPIO5为上拉模式（引脚上拉）。

    // 连接AP
    // 定义热点配置
    WifiDeviceConfig config = {0};
    // 设置热点配置中的SSID
    strcpy(config.ssid, PARAM_HOTSPOT_SSID);
    // 设置热点配置中的密码
    strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
    // 设置热点配置中的加密 方式
    config.securityType = PARAM_HOTSPOT_TYPE;
    // 等待100ms
    osDelay(10);
    // 连接到热点
    int netId = ConnectToHotspot(&config);
    // 检查是否成功连接到热点
    if (netId < 0)
    {
        printf("Connect to AP failed!\r\n");
        return;
    }


    // 初始化并启动MQTT任务
    MqttTaskInit();                                                    
    const char *host = PARAM_SERVER_ADDR;                               // MQTT服务器IP地址
    unsigned short port = atoi(PARAM_SERVER_PORT);                      // MQTT服务器端口
    const char *clientId = "Pegasus0001";                               // MQTT客户端ID
    const char *username = "nisa";                                        // MQTT服务器用户名
    const char *password = "123456";                                        // MQTT服务器密码
    if (MqttTaskConnect(host, port, clientId, username, password) != 0) // 连接MQTT服务器
    {
        // 连接失败，输出错误信息并退出
        printf("Connect to MQTT server failed!\r\n");
        return;
    }

    //循环
    while (1)
    {
         char* flag1="50";//1有水0没水 每次循环都要设成有水 如果响了就设置成没水
        IotGpioValue value=IOT_GPIO_VALUE0;
        //按钮的状态给value
        IoTGpioGetInputVal(BUTTON_GPIO, &value);
        //不用赋值给灯了 因为下面让蜂鸣器亮会有低波 蜂鸣器响是因为方波 方波有低压 灯亮//IoTGpioSetOutputVal(LED_GPIO, value);//引脚9被设置成输出 这里IoTGpioSetOutputVal设置它的输出值 
        if(value==IOT_GPIO_VALUE1){//没水响 没水-按钮没有被按下-高电压-响
            //设置引脚9为pwm
            hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_PWM0_OUT);
            IoTGpioSetDir(HI_IO_NAME_GPIO_9, IOT_GPIO_DIR_OUT);
            IoTPwmInit(HI_PWM_PORT_PWM0);
            IoTPwmStart(HI_PWM_PORT_PWM0, 20, 4000);
            osDelay(100);
            IoTPwmStop(HI_PWM_PORT_PWM0);
            //设置引脚9为gpio
            //!!!下面让灯关闭 设置引脚9为输出gpio 因为蜂鸣器和led用同一个引脚，想再次运行蜂鸣器需要重新设置引脚9为pwm
            hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
            IoTGpioSetDir(HI_IO_NAME_GPIO_9, IOT_GPIO_DIR_OUT);
            IoTGpioSetOutputVal(HI_IO_NAME_GPIO_9, IOT_GPIO_VALUE1);

            flag1="0";
   
        }




    //订阅者（还未用到 但已实现）
    // 订阅主题"test/b"
    //开发板接受bai_topic_one订阅的消息
    char *stopic = "bai_topic_one";            // 主题
    int rc = MqttTaskSubscribe(stopic); // 订阅主题
    if (rc != 0)
    {
        // 订阅失败，输出错误信息
        printf("MQTT Subscribe failed!\r\n");
//现在遇到了bug就是5秒发送一次数据 但是20词之后会自己断开连接 发送不了 
//解决方法就是断开连接 就重新初始化 再连一次
        //重新连接mqtt
    
        MqttTaskInit();                                                    
        const char *host = PARAM_SERVER_ADDR;                               // MQTT服务器IP地址
        unsigned short port = atoi(PARAM_SERVER_PORT);                      // MQTT服务器端口
        const char *clientId = "Pegasus0001";                               // MQTT客户端ID
        const char *username = "nisa";                                        // MQTT服务器用户名
        const char *password = "123456";                                        // MQTT服务器密码
        if (MqttTaskConnect(host, port, clientId, username, password) != 0) // 连接MQTT服务器
        {
        // 连接失败，输出错误信息并退出
          printf("Connect to MQTT server failed!\r\n");
        return;
        }
    }
    // 输出订阅成功信息
    printf("MQTT Subscribe OK\r\n");

    //发布者
    // 开发板向47.120.10.61的18083端口的mqtt服务器的bai_topic订阅发送消息
    char *ptopic = "bai_topic_two"; //不能用bai_topic_pub 因为开发板的发pub对于spring就是sub 所以发送接收名字一致就行                           // 主题
    char *payload = flag1; // 消息内容
   //为什么springboot的项目每发一条信 springboot都能收到息 
   //原因是 spring中订阅者和发布者订阅的名字是一样的，所以能收到
    //所以为了防止混淆 名字要不同（相同好像也行）
    rc = MqttTaskPublish(ptopic, payload);              // 发布消息
    if (rc != 0)
    {
        printf("MQTT Publish failed!\r\n");            // 发布失败，输出错误信息
    }else{
         printf("MQTT Publish OK\r\n");    // 发布成功，输出成功信息
    }
                     

    osDelay(500);
    }
}
// 入口函数
static void GpioEntry(void)
{
    // 定义线程属性
    osThreadAttr_t attr = {0};
    // 线程属性设置：设置线程名称
    attr.name = "GpioTask";
    // 线程属性设置：设置线程栈大小
    attr.stack_size = 4096;
    // 线程属性设置：设置线程优先级
    attr.priority = osPriorityNormal;

    // 创建线程
    if (osThreadNew(GpioTask, NULL, &attr) == NULL)
    {
        printf("[GpioDemo] Create GpioTask failed!\n");
    }
}

// 运行入口函数
// ohos_init.h 中定义的宏，让函数在系统启动时执行
SYS_RUN(GpioEntry);
